package com.baj.ldap.service.impl;

import com.baj.ldap.entry.Person;
import com.baj.ldap.repository.UserRepository;
import com.baj.ldap.service.PersonService;
import com.baj.ldap.util.LdapResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.ldap.core.AttributesMapper;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.filter.Filter;
import org.springframework.ldap.query.ContainerCriteria;
import org.springframework.ldap.query.LdapQuery;
import org.springframework.stereotype.Service;

import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import java.util.List;

import static org.springframework.ldap.query.LdapQueryBuilder.query;

@Slf4j
@Service
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class PersonServiceImpl implements PersonService {

    private final UserRepository personRepository;

    @Autowired
    private LdapTemplate ldapTemplate;

    @Value("${spring.ldap.base}")
    private String base;

    public List<String> getDepartmentList(Filter filter) {
        return ldapTemplate.search(base, filter.encode(), new AttributesMapper() {
            @Override
            public String mapFromAttributes(Attributes attr) throws NamingException {
                String distinguishedName = null;
                try {
                    distinguishedName = attr.get("distinguishedName").get().toString();
                } catch (javax.naming.NamingException e) {
                    e.printStackTrace();
                }
                distinguishedName = StringUtils.substringBefore(distinguishedName, base);

                return StringUtils.substringBeforeLast(distinguishedName, ",");
            }
        });
    }

//    @Override
//    public List<LdapUserVO> getUserNamesByQuery(String query) {
//        return ldapTemplate.search(
//                query().countLimit(15)
//                        .where("objectClass").is("user")
//                        .and("sAMAccountName").isPresent()
//                        .and(query()
//                                .where("sAMAccountName").like("*" + query + "*")
//                                .or("sAMAccountName").is(query)
//                                .or("displayName").like("*" + query + "*")
//                                .or("displayName").is(query))
//                ,
//                (AttributesMapper<LdapUserVO>) attrs -> {
//                    LdapUserVO ldapUser = new LdapUserVO();
//                    Attribute attr = attrs.get(ldapUserSearch);
//                    if (attr != null && attr.get() != null) {
//                        ldapUser.setUserName(attr.get().toString());
//                    }
//                    attr = attrs.get("displayName");
//                    if (attr != null && attr.get() != null) {
//                        ldapUser.setDisplayName(attr.get().toString());
//                    }
//                    return ldapUser;
//                });
//    }

    public LdapResult create(Person person) {
        ldapTemplate.create(person);
        return LdapResult.ok();
    }

    public LdapResult findOne(String key, String value) {
        ContainerCriteria criteria = query().where(key).is(value);
        Person person = ldapTemplate.findOne(criteria, Person.class);
        return LdapResult.ok(person);
    }

    public LdapResult findList(String key, String value) {
        LdapQuery criteria = query().countLimit(100).where(key).is(value);
        List<Person> list = ldapTemplate.find(criteria, Person.class);
        return LdapResult.ok(list);
    }

    public LdapResult findByCn(String cn) {
        ContainerCriteria criteria = query().countLimit(100).where("cn").is(cn);
        List<Person> list = ldapTemplate.find(criteria, Person.class);
        return LdapResult.ok(list);
    }


    public LdapResult modifyPerson(Person person) {
        ldapTemplate.update(person);
        return LdapResult.ok();
    }

    public LdapResult deletePerson(Person person) {
        ldapTemplate.delete(person);
        return LdapResult.ok();
    }

    /**
     * 查询全部
     *
     * @return {@link LdapResult}
     */
    @Override
    public LdapResult listAllPerson() {
        Iterable<Person> personList = personRepository.findAll();
//        personList.forEach(person -> person.setUserPassword(LdapUtils.asciiToString(person.getUserPassword())));
        return LdapResult.ok(personList);
    }

    /**
     * 保存
     *
     * @param person {@link Person}
     */
    @Override
    public LdapResult save(Person person) {
        Person p = personRepository.save(person);
        log.info("用户保存成功");
        return LdapResult.ok(p);
    }

    /**
     * 删除
     *
     * @param person {@link Person}
     */
    @Override
    public LdapResult delete(Person person) {
        personRepository.delete(person);
        log.info("删除用户成功");
        return LdapResult.ok();
    }



}
